package com.lhy.framework.beans.factory;

import com.lhy.framework.beans.BeansException;
import com.lhy.framework.beans.PropertyValue;
import com.lhy.framework.beans.PropertyValues;
import com.lhy.framework.beans.factory.factory.BeanDefinition;
import com.lhy.framework.beans.factory.factory.BeanFactoryPostProcessor;
import com.lhy.framework.core.io.DefaultResourceLoader;
import com.lhy.framework.core.io.Resource;
import com.lhy.framework.utils.StringValueResolver;

import java.io.IOException;
import java.util.List;
import java.util.Properties;

/**
 * @Title:
 * @Description: 功能概述:
 * @Author: lihaiyang
 * @version: 1.0 .
 * @Date: 2022-09-14 10:51
 * @Copyright: Copyright(c)2022 RedaFlight.comAll Rights Reserved
 */
public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor {

    public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";

    public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";

    private String location;

    @Override
    public void postProcessBeanFactory(ConfigurablelistableBeanFactory beanFactory) throws BeansException {
        try {
            // 加载配置文件
            DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
            Resource resource = resourceLoader.getResource(location);
            // 占位符替换属性值
            Properties properties = new Properties();
            properties.load(resource.getInputStream());

            List<String> beanDefinitionNames = beanFactory.getBeanDefinitionNames();
            for (String beanName : beanDefinitionNames) {
                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
                PropertyValues propertyValues = beanDefinition.getPropertyValues();
                for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {
                    Object value = propertyValue.getValue();
                    if (!(value instanceof String)) {
                        continue;
                    }
                    value =  resolvePlaceholder(properties, (String) value);
                    propertyValue.setValue(value);
                }
            }
            // 向容器中添加字符串解析器，供解析@Value注解使用
            PlaceholderResolvingStringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(properties);
            beanFactory.addEmbeddedValueResolver(valueResolver);

        } catch (IOException e) {
            throw new BeansException("cloud not load properties", e);
        }
    }

    private String resolvePlaceholder(Properties properties, String value) {
        String valStr = value;
        int startIndex = valStr.indexOf(DEFAULT_PLACEHOLDER_PREFIX);
        int endIndex = valStr.indexOf(DEFAULT_PLACEHOLDER_SUFFIX);
        StringBuilder buffer = new StringBuilder(valStr);
        if (startIndex != -1 && endIndex != -1 && endIndex > startIndex) {
            String propKey = valStr.substring(startIndex + 2, endIndex);
            String propVal = properties.getProperty(propKey);
            // 替换${}为具体的值
            buffer.replace(startIndex, endIndex + 1, propVal);

//                        propertyValues.addPropertyValue(new PropertyValue(propertyValue.getName(), ));
        }
        return buffer.toString();
    }

    public void setLocation(String location) {
        this.location = location;
    }

    private class PlaceholderResolvingStringValueResolver implements StringValueResolver {

        private final Properties properties;

        private PlaceholderResolvingStringValueResolver(Properties properties) {
            this.properties = properties;
        }

        @Override
        public String resolveStringValue(String valStr) {
            return PropertyPlaceholderConfigurer.this.resolvePlaceholder(properties, valStr);
        }
    }

}
